<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 数据劫持  ==> 监听对象的所有属性 劫持了这个对象
        //             我们对这个对象的属性操作的时候，我都能知道~~~
        // obj.msg         ==> getter 
        // obj.msg = 'hi'  ==> setter 

        // 数据劫持+发布订阅

        // Vue是一个数据驱动的框架 
        // MVVM 
        // M : Model       数据模型 
        // V : View        视图
        // VM: viewModel   视图数据模型 ==> Vue实例vm

        // 当数据变化了 ==通过vm做了处理=> 更新视图

        // 响应式 ==> 数据变化了，Vue响应式的更新视图 

        // data(){
        //     return {
        //         msg:'hi'
        //     }
        // }

        // this.msg = 'hello'  ==> 视图更新 
        // 当我们去设置data中的属性值的时候，触发了setter函数 ，
        // setter函数里面就可以去做一些更新视图的操作 


        // 定义个函数，update，来表示做视图更新的操作
        // let data = {
        //     msg:'hello',
        //     age: 18,
        //     // 如果对象里面嵌套对象，还会继续递归的监听对象的所有属性 
        //     demo:{
        //         name:{

        //         }
        //     }
        // }

        const update = function(){
            // 内部做一些视图更新的逻辑~~~ 
            console.log('视图更新啦~~~')
        }

        // 我想要 data.msg变化了，就去更新视图 
        // data.msg  ==> 


        // 定义一个defineReactive 将data数据做监听，响应式处理 
        // 这个函数的作用就是对某个对象的属性做监听
        function defineReactive(obj, key, val){
            // defineReactive(obj, 'age', 18)
            Object.defineProperty(obj, key, {
                configurable:true,
                enumerable:true,
                // obj.age 
                get:function reactiveGetter(){
                    // 获取了data中的值 
                    console.log('触发了getter函数')
                    return val 
                },
                // obj.age = '19'
                set:function reactiveSetter(newVal){
                    console.log('触发了setter函数')
                    // 修改了data中的值 
                    if (val === newVal) return 
                    // 更新视图 
                    update(newVal) // vm.msg = 'hi' newVal ==> hi
                }
            })
        }

        // initData 
        function observer(value){
            // {msg:'hell',age:18}
            // ['msg', 'age']
            // 实际上会做递归处理，
            Object.keys(value).forEach(key => {
                // value => data 
                // key   =>  msg 
                // value[key]  => I am hi 
                // 
                // defineReactive(obj, 'age', 18)
                defineReactive(value, key, value[key])
            })
        }


        // 声明一个Vue类，构造函数 
        class Vue {
            // new Vue的时候 ，调用 constructor()
            constructor(options){
                // vm._data = options.data 
                this._data = options.data 
                // 对data中所有的属性做监听 
                observer(this._data) 

                // {
                //     test:'I am hi~~',
                //     age:18
                // }
            }
        }



        const vm = new Vue({
            data:{
                test:'I am hi~~',
                age:18,
                demo:'wa~太难了~凉凉'
            }
        })

        // vm._data.test = 'hello world '

        // proxy 

        // Watcher  / Dep 


    </script>
</body>
</html>